package bgapi

import (
	"bgs/db"
	sqlc "bgs/db/sqlc"
	storeService "bgs/service/store"
	"bgs/util"
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"github.com/nsqio/go-nsq"
	"go.uber.org/zap"
)

var (
	lastStoreFanMessage *StoreFanMessage = nil
)

// StoreFanMessage StoreFan message struct
type StoreFanMessage struct {
	TS   int64 `json:"ts"`
	Data struct {
		// 被关注品牌id
		StoreID int64 `json:"store_id"`
		// 作为粉丝的用户id
		FollowerUserID int64 `json:"follower_user_id"`

		// 被关注时间
		BeFollowed int64 `json:"be_followed"`

		// 默认用user.nick_name
		AliasName string `json:"alias_name"`
	} `json:"data"`
}

// StoreFanHandler StoreFan message handler
type StoreFanHandler struct {
	dao          *db.PgDao
	slog         *zap.SugaredLogger
	storeService *storeService.StoreServiceImp
}

// NewStoreFanHandler create a new handler for StoreFan
func NewStoreFanHandler(
	pgdao *db.PgDao,
	slog *zap.SugaredLogger,
	storeService *storeService.StoreServiceImp,
) *StoreFanHandler {
	return &StoreFanHandler{
		dao:          pgdao,
		slog:         slog.With("module", "StoreFanHandler"),
		storeService: storeService,
	}
}

// HandleMessage implements the Handler interface.
func (h *StoreFanHandler) HandleMessage(m *nsq.Message) error {
	if len(m.Body) == 0 {
		// Returning nil will automatically send a FIN command to NSQ to mark the message as processed.
		return nil
	}

	h.slog.Infof("StoreFanMessage=>%s", string(m.Body))

	v := &StoreFanMessage{}
	if decodeErr := json.NewDecoder(bytes.NewReader(m.Body)).Decode(v); decodeErr != nil {
		return fmt.Errorf("无法解析信息[StoreFanMessage]: %v", decodeErr)
	}
	if lastStoreFanMessage != nil && lastStoreFanMessage.TS >= v.TS {
		h.slog.Infof("过时的消息: lastStoreFanMessage.TS:%v,v.TS:%v", lastStoreFanMessage.TS, v.TS)
		return nil
	}

	ctx := context.Background()
	storeID := v.Data.StoreID
	err := h.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {
		_, err = q.UpsertStoreFan(ctx, sqlc.UpsertStoreFanParams{
			StoreID:        storeID,
			FollowerUserID: v.Data.FollowerUserID,
			BeFollowed:     util.MsToGoTime(v.Data.BeFollowed),
			AliasName:      v.Data.AliasName,
		})
		if err != nil {
			return
		}
		h.slog.Infof("a StoreFanHandler-插入/更新品牌粉丝关系 ok")

		err = h.storeService.UpdateStoreStatFansCountSinceUpsertStoreFan(ctx, q, storeID)
		if err != nil {
			return
		}
		h.slog.Infof("b StoreFanHandler-更新品牌统计的fans_count ok")

		return
	})

	if err != nil {
		return err
	}

	lastStoreFanMessage = v
	// Returning a non-nil error will automatically send a REQ command to NSQ to re-queue the message.
	return nil
}
